package vip.xiaonuo.common.util;

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class PasswordUtil {

    private static final String LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
    private static final String UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String NUMBERS = "0123456789";
    private static final String SPECIALS = "!@#$%^&*()-_=+[]{}|;:',.<>?/";
    private static final Random random = new Random();


    //生成8-16位复杂密码，包括数字，字母大小写，特殊字符，并且数字，字母不连续
    public static String generatePassword() {

        // 8-16位
        int length = 8 + random.nextInt(9);
        StringBuilder password = new StringBuilder();
        Set<Character> lastTwo = new HashSet<>();

        while (password.length() < length) {
            char nextChar;
            do {
                // 随机选择字符类型
                int type = random.nextInt(4);
                switch (type) {
                    case 0:
                        nextChar = LOWERCASE.charAt(random.nextInt(LOWERCASE.length()));
                        break;
                    case 1:
                        nextChar = UPPERCASE.charAt(random.nextInt(UPPERCASE.length()));
                        break;
                    case 2:
                        nextChar = NUMBERS.charAt(random.nextInt(NUMBERS.length()));
                        break;
                    default:
                        nextChar = SPECIALS.charAt(random.nextInt(SPECIALS.length()));
                        break;
                }
            } while (lastTwo.contains(nextChar) &&
                    (Character.isLetterOrDigit(lastTwo.iterator().next()) &&
                            Character.isLetterOrDigit(nextChar)));

            password.append(nextChar);
            lastTwo.add(nextChar);
            if (lastTwo.size() > 2) {
                lastTwo.clear();
                lastTwo.add(nextChar);
            }
        }

        return password.toString();
    }

    // 检查密码强度
    public static boolean checkPasswordStrength(String password) {
        // 长度至少8位
        if (password == null || password.length() < 8) {
            return false;
        }

        // 必须包含大小写字母、数字和特殊字符
        boolean hasUpper = false;
        boolean hasLower = false;
        boolean hasDigit = false;
        boolean hasSpecial = false;

        for (char c : password.toCharArray()) {
            if (Character.isUpperCase(c)) hasUpper = true;
            else if (Character.isLowerCase(c)) hasLower = true;
            else if (Character.isDigit(c)) hasDigit = true;
            else hasSpecial = true;
        }

        if (!(hasUpper && hasLower && hasDigit && hasSpecial)) {
            return false;
        }

        // 检查连续字符或重复字符
        if (containsSequentialChars(password) || containsRepeatedChars(password)) {
            return false;
        }

        return true;
    }

    // 检查连续字符
    private static boolean containsSequentialChars(String str) {
        for (int i = 0; i < str.length() - 2; i++) {
            char c1 = str.charAt(i);
            char c2 = str.charAt(i + 1);
            char c3 = str.charAt(i + 2);

            // 数字连续
            if (Character.isDigit(c1) && Character.isDigit(c2) && Character.isDigit(c3)) {
                if (c2 == c1 + 1 && c3 == c2 + 1) {
                    return true;
                }
                if (c2 == c1 - 1 && c3 == c2 - 1) {
                    return true;
                }
            }

            // 字母连续
            if (Character.isLetter(c1) && Character.isLetter(c2) && Character.isLetter(c3)) {
                if (c2 == c1 + 1 && c3 == c2 + 1) {
                    return true;
                }
                if (c2 == c1 - 1 && c3 == c2 - 1) {
                    return true;
                }
            }
        }
        return false;
    }

    // 检查重复字符
    private static boolean containsRepeatedChars(String str) {
        for (int i = 0; i < str.length() - 2; i++) {
            char c1 = str.charAt(i);
            char c2 = str.charAt(i + 1);
            char c3 = str.charAt(i + 2);

            if (c1 == c2 && c2 == c3) {
                return true;
            }
        }
        return false;
    }
}